﻿// Developer Express Code Central Example:
// World Wide CRM Demo
// 
// The World Wide CRM demo is a next generation application with outstanding
// navigation capabilities and shows a reimagined view of customer contact and
// management. This demo showcases many of the most popular features of the
// WinForms Subscription.
// 
// You can find sample updates and versions for different programming languages here:
// http://www.devexpress.com/example=E3993

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace DevExpress.CrmDemo.Win.Controls {
    public partial class MonthSlider : UserControl {
        public MonthSlider() {
            InitializeComponent();
            sliderXOffset = imgLeft.Width / 2;
        }

        private void MonthSlider_Load(object sender, EventArgs e) {
            InitializeSlider();
        }

        int sliderXOffset;

        Color DarkGrayColor = Color.FromArgb(51, 51, 51);
        Color MidGrayColor = Color.FromArgb(77, 77, 77);
        Color LightGrayColor = Color.FromArgb(102, 102, 102);

        void InitializeSlider() {
            int totalMonths = 15;

            // End is first of next month

            EndDate = new DateTime(DateTime.Now.AddMonths(1).Year, DateTime.Now.AddMonths(1).Month, 1);
            StartDate = EndDate.AddMonths(-totalMonths);

            InitLayoutPanel(totalMonths, StartDate);

            LeftThumbPosition = 4;
            RightThumbPosition = totalMonths - 2;

            SnapSliders();
        }

        bool tableLayoutPanelInitialized = false;

        void InitLayoutPanel(int totalMonths, DateTime startDate) {
            tableLayoutPanel1.ColumnCount = totalMonths;

            float width = 100F / (float)totalMonths;

            tableLayoutPanel1.ColumnStyles.Clear();

            for (int i = 0; i < totalMonths; i++) {
                tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, width));

                DateTime date = startDate.AddMonths(i);

                Label label = new Label();
                label.AutoSize = false;
                label.Text = date.ToString("MMM").ToUpper() + " " + date.Year.ToString();
                label.Dock = DockStyle.Fill;
                label.TextAlign = ContentAlignment.MiddleCenter;
                label.Margin = new System.Windows.Forms.Padding(0);
                label.BackColor = MidGrayColor;
                tableLayoutPanel1.Controls.Add(label, i, 0);
            }

            tableLayoutPanelInitialized = true;
        }

        Point cursorDragStart;
        int controlDragStartX;

        private DateTime StartDate { get; set; }
        private DateTime EndDate { get; set; }

        private int leftThumbPosition;

        private int LeftThumbPosition {
            get { return leftThumbPosition; }
            set {
                if (leftThumbPosition != value) {
                    leftThumbPosition = value;
                    RefreshSelection();
                }
            }
        }

        private int rightThumbPosition;

        private int RightThumbPosition {
            get { return rightThumbPosition; }
            set {
                if (rightThumbPosition != value) {
                    rightThumbPosition = value;
                    RefreshSelection();
                }
            }
        }

        public DateTime SelectionStartDate {
            get { return StartDate.AddMonths(LeftThumbPosition); }
        }

        public DateTime SelectionEndDate {
            get { return StartDate.AddMonths(RightThumbPosition); }
        }

        void RefreshSelection() {
            for (int i = 0; i < tableLayoutPanel1.ColumnCount; i++) {
                Label label = (Label)tableLayoutPanel1.GetControlFromPosition(i, 0);

                if (i >= LeftThumbPosition && i < RightThumbPosition) {
                    label.BackColor = MidGrayColor;
                } else {
                    label.BackColor = DarkGrayColor;
                }
            }
        }

        private int LeftX {
            get {
                return imgLeft.Location.X + sliderXOffset;
            }
            set {
                int newX = value;

                decimal blockSize = tableLayoutPanel1.Width / tableLayoutPanel1.ColumnCount;

                // set limits

                newX = Math.Max(tableLayoutPanel1.Location.X, newX);
                newX = Math.Min(RightX - (int)blockSize, newX);

                imgLeft.Location = new Point(newX - sliderXOffset, imgLeft.Location.Y);

                decimal positionRelative = imgLeft.Location.X - tableLayoutPanel1.Location.X;

                int blocks = (int)Math.Round(positionRelative / blockSize);

                LeftThumbPosition = blocks;
            }
        }

        private int RightX {
            get {
                return imgRight.Location.X + sliderXOffset;
            }
            set {
                int newX = value;

                decimal blockSize = tableLayoutPanel1.Width / tableLayoutPanel1.ColumnCount;

                // set limits

                newX = Math.Max(LeftX + (int)blockSize, newX);
                newX = Math.Min(newX, tableLayoutPanel1.Location.X + tableLayoutPanel1.Width);

                imgRight.Location = new Point(newX - sliderXOffset, imgRight.Location.Y);

                decimal positionRelative = imgRight.Location.X - tableLayoutPanel1.Location.X;

                int blocks = (int)Math.Round(positionRelative / blockSize);

                RightThumbPosition = blocks;
            }
        }


        private void img_MouseDown(object sender, MouseEventArgs e) {
            PictureBox pb = (PictureBox)sender;

            cursorDragStart = Cursor.Position;

            if (pb == imgLeft)
                controlDragStartX = LeftX;
            else
                controlDragStartX = RightX;

            pb.DoDragDrop(pb.Text, DragDropEffects.All);
        }

        private void img_QueryContinueDrag(object sender, QueryContinueDragEventArgs e) {
            Point currentCursorPosition = Cursor.Position;
            Point cursorDragDelta = new Point(currentCursorPosition.X - cursorDragStart.X, currentCursorPosition.Y - cursorDragStart.Y);

            PictureBox pb = (PictureBox)sender;

            if (pb == imgLeft) {
                LeftX = controlDragStartX + cursorDragDelta.X;
            } else {
                RightX = controlDragStartX + cursorDragDelta.X;
            }

            if (e.Action == DragAction.Drop) // this indicates drag end
            {
                SnapSliders();
                OnChanged(EventArgs.Empty);
            }

            Cursor.Current = Cursors.Arrow;
        }

        public delegate void ValueChangedEventHandler(object sender, EventArgs e);
        public event ValueChangedEventHandler ValueChanged;

        private void OnChanged(EventArgs e) {
            if (ValueChanged != null)
                ValueChanged(this, e);
        }

        void SnapSliders() {
            int blockSize = tableLayoutPanel1.Width / tableLayoutPanel1.ColumnCount;

            RightX = RightThumbPosition * blockSize + tableLayoutPanel1.Location.X;
            LeftX = LeftThumbPosition * blockSize + tableLayoutPanel1.Location.X;
        }

        private void tableLayoutPanel1_Resize(object sender, EventArgs e) {
            if (tableLayoutPanelInitialized)
                SnapSliders();
        }

        private void imgRight_GiveFeedback(object sender, GiveFeedbackEventArgs e) {
            e.UseDefaultCursors = false;
        }

        private void imgLeft_GiveFeedback(object sender, GiveFeedbackEventArgs e) {
            e.UseDefaultCursors = false;
        }
    }
}